package dao;

import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.UnexpectedException;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import model.Vokabel;

import org.dom4j.Document;
import org.dom4j.Element;

import xml.Dom4JXmlWriter;
import xml.DomHolder;

public class VokabelDaoImpl implements VokabelDao
{
	private Document doc = DomHolder.getInstance().getDom();
	private String path;

	public VokabelDaoImpl(String path)
	{
		setpath(path);
	}
	
	private void setpath(String path)
	{
		if(path == null)
			throw new NullPointerException("VokabelDaoImpl: path must not be null");
		
		this.path = path;
	}
	

	@Override
	public Vokabel persist( Vokabel vok )
	{
		if (vok.getId() == null)
			insertElement( vok );
		else
			update( vok );
		
		return vok;
	}
	

	public Vokabel insertElement(Vokabel vok)
	{
		String id = UUID.randomUUID().toString();
		
		Element root = doc.getRootElement();
		
		Element vokabel = root.addElement("vokabel");
		vokabel.addAttribute("id", id);
		
		
		Element german = vokabel.addElement("german");
		german.addText(vok.getGerman());
		
		Element english = vokabel.addElement("english");
		english.addText( vok.getEnglish() );
		
		Element lvlGerman = vokabel.addElement("lvlGerman");
		lvlGerman.addAttribute("lvl", ""+vok.getLvlGerman());

		Element lvlEnglish = vokabel.addElement("lvlEnglish");
		lvlEnglish.addAttribute("lvl", ""+vok.getLvlEnglish());
		
		write(); 
		return vok ;
		
		
	}

	public void update(Vokabel vokabel)
	{
		Element root = doc.getRootElement();
		Element vokabelNode = findElementById( vokabel );
		
		vokabelNode.element("german").setText( vokabel.getGerman() );
		
		vokabelNode.element( "english").setText( vokabel.getEnglish() );
		
		vokabelNode.element( "lvlGerman" ).setAttributeValue( "lvl" , ""+vokabel.getLvlGerman() );
		
		vokabelNode.element( "lvlEnglish" ).setAttributeValue( "lvl" ,""+vokabel.getLvlEnglish() );
		
		write();
		
		
	}
	
	public List<Vokabel> getAllVokabelFromXml() 
	{
		List<Vokabel> vokablen = new LinkedList<Vokabel>();
		List<Element> vokabelNodes = doc.getRootElement().elements();
		for (Element e :  vokabelNodes)
		{
			vokablen.add(createVokabelFromXmlElementNode(e));
		}
		
		return vokablen;
	}
	
	@Override
	public boolean remove(Vokabel vokabel)
	{
		if (vokabel == null)
			throw new NullPointerException("VokabelDaoImpl remove: vokabel must not be null");
		
		doc.getRootElement().remove(findElementById(vokabel));
		write();
		return true;
	}
	
	
	@Override
	public Vokabel findElementById(String id) 
	{
		List<Element> vokabeln = doc.getRootElement().elements("vokabel");
		for (Element e : vokabeln)
			if(e.attributeValue("id").equals(id))
			{
				return createVokabelFromXmlElementNode(e);
			}
		return null;
	}
	
	public Element findElementById(Vokabel vokabel) 
	{
//		doc = DomHolder.getInstance().getDom();
		List<Element> vokabeln = doc.getRootElement().elements("vokabel");
		for (Element e : vokabeln)
			if(e.attributeValue("id").equals(vokabel.getId()))
			{
				return e;
			}
		return null;
	}
	
	private Vokabel createVokabelFromXmlElementNode( Element vokabelNode) 
	{
		String id = vokabelNode.attributeValue("id");
		
		String german = vokabelNode.elementTextTrim("german");
		
		String english = vokabelNode.elementTextTrim("english");
		
		Element el = vokabelNode.element( "lvlGerman" );
		int lvlGerman = Integer.parseInt( el.attributeValue( "lvl") );

		el = vokabelNode.element( "lvlEnglish" );
		int lvlEnglish = Integer.parseInt( el.attributeValue( "lvl") );
//		int lvlEnglish = Integer.parseInt( vokabelNode.attributeValue("lvlEnglish", "lvl") );
		
				
		Vokabel vokabel = new Vokabel(german, english, lvlGerman, lvlEnglish);
		
		vokabel.setId(id);
		
		return vokabel;
	}
	
	private boolean write() 
	{
		try
		{
			Dom4JXmlWriter writer = new Dom4JXmlWriter();
			writer.writeXml(path);
			return true;
		}
		catch (Exception e)
		{
			throw new IllegalArgumentException("IO Exception");
		}
	}
	
	@Override
	public List<Vokabel> getAllVokabel() 
	{
		List<Element> list = doc.getRootElement().elements( "vokabel" );
		List<Vokabel> result = new LinkedList<Vokabel>();
		if(list.size() > 0)
		{
			for(Element e : list)
			{
				Vokabel vok = createVokabelFromXmlElementNode( e );
				result.add(vok);
			}
			
			return result;
		}
		else
			return null;
		
	}



}
